package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.client.ItemClient;
import com.hmall.client.UserClient;
import com.hmall.common.dto.Address;
import com.hmall.common.dto.Item;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.RequestParams;
import com.hmall.order.service.IOrderDetailService;
import com.hmall.order.service.IOrderLogisticsService;
import com.hmall.order.service.IOrderService;
import com.hmall.order.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Or;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    private ItemClient itemClient;

    @Autowired
    private IOrderDetailService orderDetailService;

    @Autowired
    private UserClient userClient;

    @Autowired
    private IOrderLogisticsService orderLogisticsService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    @Transactional
    public Long createOrder(RequestParams params) {
        // 创建订单对象
        Order order = new Order();
        // 1. 根据雪花算法生成订单id
        // 2. 商品微服务提供FeignClient，实现根据id查询商品的接口(已完成)
        // 3. 根据itemId查询商品信息
        Item item = itemClient.queryItemById(params.getItemId());
        // 4. 基于商品价格、购买数量计算商品总价：totalFee
        Long totalFee = item.getPrice() * params.getNum();
        // 5. 封装Order对象，初始status为未支付
        order.setTotalFee(totalFee);
        order.setPaymentType(params.getPaymentType());
        order.setUserId(UserHolder.getUser());
        order.setStatus(Order.OrderStatus.UNPAY.getState());
        // 6. 将Order写入数据库tb_order表中
        this.save(order);
        // 7. 将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setName(item.getName());
        orderDetail.setSpec(item.getSpec());
        orderDetail.setPrice(item.getPrice());
        orderDetail.setNum(params.getNum());
        orderDetail.setItemId(item.getId());
        orderDetail.setImage(item.getImage());
        orderDetail.setOrderId(order.getId());
        orderDetailService.save(orderDetail);

        // 8. 将user-service的根据id查询地址接口封装为FeignClient(已完成)
        // 9. 根据addressId查询user-service服务，获取地址信息
        Address address = userClient.findAddressById(params.getAddressId());
        // 10. 将地址封装为OrderLogistics对象，写入tb_order_logistics表
        OrderLogistics orderLogistics = new OrderLogistics();
        BeanUtils.copyProperties(address, orderLogistics);
        orderLogistics.setOrderId(order.getId());
        orderLogisticsService.save(orderLogistics);
        // 11. 在item-service提供减库存接口，并编写FeignClient(已完成)
        // 12. 调用item-service的减库存接口
        try {
            itemClient.updateStock(item.getId(), params.getNum());
        } catch (Exception e) {
            throw new RuntimeException("删减库存失败");
        }

        // 清理超时订单
        // 声明交换机名称
        String exchangeName = "delay.order.direct";
        // 定义routingkey
        String routingKey = "order.delay";
        // 消息
        String msg = order.getId().toString();
        // 设置延时
        Long delayTimeMills = 1L * 60 * 1000;
        Message message = MessageBuilder.withBody(msg.getBytes(StandardCharsets.UTF_8)).setHeader("x-delay", delayTimeMills).build();
        // 消息id
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName, routingKey, message, correlationData);
        return order.getId();
    }

    @Override
    public void cancelOrder(Long orderId) {
        // 根据id查询订单
        Order order = getById(orderId);
        // 判断是否支付，若1则已支付
        if (order.getStatus() != Order.OrderStatus.UNPAY.getState()) {
            return;
        }
        // 根据orderId，将订单状态修改为取消
        order.setStatus(Order.OrderStatus.CANCEL.getState());
        updateById(order);

        // 恢复库存
        List<OrderDetail> orderDetailList = orderDetailService.query().eq("order_id", orderId).list();
        for (OrderDetail orderDetail : orderDetailList) {
            // 获取商品购买数量
            Integer num = orderDetail.getNum();
            // 恢复商品库存
            itemClient.updateStock(orderDetail.getItemId(), num*-1);
        }

    }
}
